class Snowflake {
  constructor(workerId, datacenterId) {
    this.workerIdBits = 5 // 机器 ID 位数
    this.datacenterIdBits = 5 // 数据中心 ID 位数
    this.sequenceBits = 12 // 序列号位数

    this.maxWorkerId = -1 ^ (-1 << this.workerIdBits)
    this.maxDatacenterId = -1 ^ (-1 << this.datacenterIdBits)
    this.sequenceMask = -1 ^ (-1 << this.sequenceBits)

    this.workerIdShift = this.sequenceBits
    this.datacenterIdShift = this.workerIdBits + this.workerIdShift
    this.timestampShift = this.datacenterIdBits + this.datacenterIdShift

    this.epoch = 1735660800000 // 起始时间戳，这里设置为 2025-01-01 00:00:00

    this.workerId = workerId
    this.datacenterId = datacenterId
    this.sequence = 0
    this.lastTimestamp = -1
  }

  // 获取当前时间戳
  getCurrentTimestamp() {
    return Date.now()
  }

  // 等待下一个毫秒
  waitNextMillis(lastTimestamp) {
    let timestamp = this.getCurrentTimestamp()
    while (timestamp <= lastTimestamp) {
      timestamp = this.getCurrentTimestamp()
    }
    return timestamp
  }

  // 生成 16 位数字订单号
  generateOrderId(n = 16) {
    let timestamp = this.getCurrentTimestamp() - this.epoch

    const BASE_TIMESTAMP = 100000000 // 保证前8位非零
    timestamp += BASE_TIMESTAMP

    if (timestamp === this.lastTimestamp) {
      this.sequence = (this.sequence + 1) & this.sequenceMask
      if (this.sequence === 0) {
        timestamp = this.waitNextMillis(this.lastTimestamp)
      }
    } else {
      this.sequence = 0
    }

    this.lastTimestamp = timestamp

    const orderId = (
      (BigInt(timestamp) << BigInt(this.timestampShift)) |
      (BigInt(this.datacenterId) << BigInt(this.datacenterIdShift)) |
      (BigInt(this.workerId) << BigInt(this.workerIdShift)) |
      BigInt(this.sequence)
    ).toString()

    // 确保输出是纯数字字符串并且前面填充零使其长度为16
    return orderId.slice(0, n)
  }

  // 生成 8 位数字用户 ID
  generateUserId(n = 8) {
    // 强制长度校验
    n = Math.min(Math.max(n, 8), 10) // 限制8~10位

    // 混合因子增强
    const MODULO = 9000000000 // 9,000,000,000
    const BASE = 1000000000 // 1,000,000,000 (10位数起点)

    let timestamp = this.getCurrentTimestamp() - this.epoch
    const safeMod = (timestamp % MODULO) + BASE
    return safeMod.toString().slice(-n)
  }

  getRandomFile = (files) => {
    if (!Array.isArray(files) || files.length === 0) {
      throw new Error('文件为空/不是一个数组')
    }
    // 生成一个随机索引
    const randomIndex = Math.floor(Math.random() * files.length)
    // 返回随机选择的文件名
    return files[randomIndex]
  }
}

module.exports = Snowflake
